package com.biscuit.page.basicservice.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.apache.commons.lang3.StringUtils;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

/**
 * @author mazihao
 * @createTime 2024/3/22 17:42
 */
public class JwtUtil {

    private final static String SALT = "token!@#$%^7890";

    public static String getToken(Map<String, String> dataMap, int expire) {
        BaseExceptionUtil.throwException(!dataMap.isEmpty(), "存储内容为空，生成 Token 失败");
        JWTCreator.Builder builder = JWT.create();

        // 设置存储内容
        dataMap.forEach(builder::withClaim);

        // 设置加密时间
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, expire);
        builder.withExpiresAt(calendar.getTime());

        return builder.sign(Algorithm.HMAC256(SALT));
    }

    public static String getToken(String userKey, long expire) {
        // 校验加密内容是否为空
        BaseExceptionUtil.throwException(StringUtils.isNotBlank(userKey), "加密内容为空，生成 Token 失败");

        // 计算出过期时间
        LocalDateTime expireDateTime = LocalDateTime.now().plusSeconds(expire);
        Date expireDate = Date.from(expireDateTime.atZone(ZoneId.systemDefault()).toInstant());

        // 获取 Jwt 构造器
        JWTCreator.Builder builder = JWT.create();

        // 设置加密内容
        builder.withSubject(userKey);

        // 设置加密时间
        builder.withExpiresAt(expireDate);

        // 设置加密盐值，生成 token 并返回
        return builder.sign(Algorithm.HMAC256(SALT));
    }

    public static String getUserKey(String token) {
        DecodedJWT decodedJwt = JWT.require(Algorithm.HMAC256(SALT)).build().verify(token);
        return decodedJwt.getSubject();
    }

    public static String expire(String token, int expire) {
        DecodedJWT decodedJwt = JWT.require(Algorithm.HMAC256(SALT)).build().verify(token);

        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, expire);

        return JWT.create()
                .withSubject(decodedJwt.getSubject())
                .withExpiresAt(calendar.getTime())
                .sign(Algorithm.HMAC256(SALT));
    }

    public static void verify(String token) {
        JWT.require(Algorithm.HMAC256(SALT)).build().verify(token);
    }

}
